package com.flot.yazb.aop.stub;

import android.app.Activity;
import android.content.Context;

import com.flot.yazb.base.model.BModel;
import com.flot.yazb.widget.utils.CommonJson;
import com.flot.yazb.widget.utils.EncodeUtils;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

/**
 * Created by fengdongfei on 2017/10/23.
 */

public abstract class StringCallBack<T  extends BModel> implements Callback<String> {
    public static final int R_OK = 200;
    public static final int R_Network_Error = 500;
    public static final int R_Unexpected_Error = 501;
    public static final int R_Unauthenticated_Error = 502;
    public static final int R_Client_Error = 503;
    public static final int R_Server_Error = 504;

    private Context mContext;
    private boolean mErrIgnore = false;
    java.lang.String errorInfo = "";

    public StringCallBack(Context context) {
        this.mContext = context;
    }

    public StringCallBack(Context context, boolean errIgnore) {
        this.mErrIgnore = errIgnore;
        this.mContext = context;
    }

    protected abstract void onSuccess(T result);

    protected abstract void onFail(String errorCode, String errorInfo);

    protected void onFail(T content) {}
    @Override
    public void onResponse(Call<String> call, Response<String> response) {
        if (!isAlive()) return;
        int errorCode = response.code();
        if (errorCode == 200) {
            errorCode = R_OK;
        } else if (errorCode == 401) {
            errorCode = R_Unauthenticated_Error;
        } else if (errorCode >= 400 && errorCode < 500) {
            errorCode = R_Client_Error;
        } else if (errorCode >= 500 && errorCode < 600) {
            errorCode = R_Server_Error;
        } else {
            errorCode = R_Unexpected_Error;
        }

        String body = EncodeUtils.decp(response.body());
        T model = fromJsonObject(body);
        if (body != null) {
            onSuccess(model);
        }

        if (null == body) {
            if (!mErrIgnore) onFail(errorCode + "", errorInfo);
            return;
        }
    }

    @Override
    public void onFailure(Call call, Throwable t) {
        if (!isAlive()) return;
        if (!mErrIgnore) {
            if (t instanceof UnknownHostException) {
                onFail(R_Network_Error + "", "请求失败");
            } else if (t instanceof SocketTimeoutException) {
                onFail(R_Network_Error + "", "请求超时");
            } else if (t instanceof IOException) {
                onFail(R_Network_Error + "", t.getMessage());
            } else {
                onFail(R_Unexpected_Error + "", t.getMessage());
            }
        }
    }


    private boolean isAlive() {
        if (mContext == null)
            return false;
        if (mContext instanceof Activity) {
            if (((Activity) mContext).isFinishing())
                return false;
        }
        return true;
    }

    @SuppressWarnings("unchecked")
    public Class<T> getClz(){
        Class<T> clazz = null;
        if (clazz==null) {
            clazz=(Class<T>)(((ParameterizedType)this.getClass().getGenericSuperclass()).getActualTypeArguments()[0]);
        }
        return clazz;
    }

    public  T fromJsonObject(String reader) {
        Class<T> cz = getClz();
        Type type = new CommonJson.ParameterizedTypeImpl(RMResponse.class, new Class[]{cz});
        return new Gson().fromJson(reader, type);
    }

    public  T fromJsonTypeToken(String reader) {
        return new Gson().fromJson(reader, new TypeToken<T>() {}.getType());
    }



}
